package com.pansoft.openplanet.util;

import android.app.Activity;
import android.content.Context;
import androidx.annotation.NonNull;
import android.text.TextUtils;

import com.efounder.chat.http.JFCommonRequestManager;
import com.efounder.chat.http.OpenEthRequest;
import com.efounder.chat.utils.AESSecretUtil;
import com.efounder.chat.utils.CommonThreadPoolUtils;
import com.efounder.chat.utils.RSAUtil;
import com.efounder.constant.EnvironmentVariable;
import com.efounder.util.AppContext;
import com.efounder.util.EnvSupportManager;
import com.efounder.utils.ResStringUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pansoft.hd.HDAccountManager;
import com.pansoft.hd.HDWalletUtil;
import com.pansoft.hd.model.EthHdWallet;
import com.pansoft.openplanet.R;
import com.pansoft.openplanet.account.model.BchGeneratorBean;
import com.pansoft.openplanet.account.model.BtcBean;
import com.pansoft.openplanet.account.model.EthBean;
import com.pansoft.openplanet.account.util.BTCAccountGenerator;
import com.pansoft.openplanet.account.util.EosAccountGenerator;
import com.pansoft.openplanet.bean.Account;
import com.pansoft.openplanet.constant.IPAssetsConstant;
import com.pansoft.openplanet.constant.TalkChainConstant;
import com.pansoft.openplanet.db.AccountDao;
import com.utilcode.util.LogUtils;
import com.utilcode.util.TimeUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Wallet;
import org.web3j.crypto.WalletFile;

import java.io.File;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Response;

import static com.efounder.frame.utils.Constants.CHAT_USER_ID;
import static com.pansoft.openplanet.util.TCRequestUtil.BASE_URL;

/**
 * 帐号管理
 */
public class TCAccountManager {

    private static final String TAG = "TCAccountManager";
    private Context mContext;
    private Disposable disposable;

    //主账户钱包的私钥
    public static String ethMainAccountPrivateKey;

    public TCAccountManager(Context mContext) {
        this.mContext = mContext;
    }

    public Disposable getDisposable() {
        return disposable;
    }

    /**
     * 检查用户通讯公钥
     * 不存在的情况下会生成并进行加密操作，然后上传服务器
     *
     * @param isCreate 如果创建新的 就不使用服务器的了
     * @param userId   用户IMuserid
     */
    public void checkAndUpdateMessageKey(final String userId, boolean isCreate, final AccountManagerListener listener) {
        if (isCreate) {
            createAndUploadIMKey(userId, listener);
            return;
        }
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("userId", userId);
        TCRequestUtil.getCommonRequest(TAG, "account/getUserSecretKeyByUserId", hashMap,
                new TCRequestUtil.TCRequestCallback() {
                    @Override
                    public void onSuccess(String response) {
                        JSONObject jsonObject = JSONObject.fromObject(response);
                        if (jsonObject.optString("result", "").equals("fail")) {
                            //通讯公钥不存在,生成新的
                            createAndUploadIMKey(userId, listener);
                        } else {

                            JSONObject secretKey = jsonObject.getJSONObject("SecretKey");
                            final String publicKey = secretKey.optString("publicKey", null);
                            final String privateKey = secretKey.optString("privateKey", null);
                            if (publicKey != null && privateKey != null) {

                                CommonThreadPoolUtils.execute(new Runnable() {
                                    @Override
                                    public void run() {

                                        //todo 20181124修改---start
//                                        Account mainAccount = new AccountDao(mContext).getMainAccountInDb();
//                                        if (ethMainAccountPrivateKey == null) {
//                                            ethMainAccountPrivateKey = PrivateKeyUtils.exportPrivateKey(mainAccount.getFileName(), "");
//                                        }
//                                        String mainPrivateKey = ethMainAccountPrivateKey;
//                                        //将私钥转为0X 开头 并且小写
//                                        if (!"0x".equals(mainPrivateKey.substring(0, 2).toLowerCase())) {
//                                            mainPrivateKey = ("0x" + mainPrivateKey).toLowerCase();
//                                        } else {
//                                            mainPrivateKey = mainPrivateKey.toLowerCase();
//                                        }

//                                        String rsaPrivateKey = null;
//                                        try {
//                                            //使用主账户私钥 加密子账户私钥
//                                            AESSecretUtil aesSecretUtil = new AESSecretUtil(mainPrivateKey);
//                                            rsaPrivateKey = aesSecretUtil.decrypt(privateKey);
//                                        } catch (Exception e) {
//                                            e.printStackTrace();
//                                            // 注意解密通讯私钥失败，是由于之前版本的错误，这里重新生成并上传通讯私钥
//                                            createAndUploadIMKey(userId, listener);
//                                            return;
//                                        }
                                        //todo 20181124修改--end
                                        //这里使用新的代码
                                        String rsaPrivateKey = null;
                                        try {
                                            //使用主账户私钥 解密通讯私钥
                                            rsaPrivateKey = decryptByMainPrivKey(privateKey);
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                            //todo 注意解密通讯私钥失败，是由于之前版本的错误，这里重新生成并上传通讯私钥
                                            createAndUploadIMKey(userId, listener);
                                            return;
                                        }

                                        //解密后存到本地
                                        EnvironmentVariable.setProperty(RSAUtil.getCurrentPrivateKey(), rsaPrivateKey);
                                        EnvironmentVariable.setProperty(RSAUtil.getCurrentPublicKey(), publicKey);

                                        //跟臧老师服务器比对，不一致则上传
                                        if (EnvironmentVariable.getProperty(CHAT_USER_ID, "").equals("")) {
                                            return;
                                        }

                                        OpenEthRequest.getUserEthByImUserId(mContext,
                                                Integer.valueOf(EnvironmentVariable.getProperty(CHAT_USER_ID, "0")),
                                                new OpenEthRequest.EthRequestListener() {
                                                    @Override
                                                    public void onSuccess(String ethAddress, String publicKey1, String RSAPublicKey) {
                                                        if (!publicKey.equals(RSAPublicKey)) {
                                                            //发送到臧老师服务器
                                                            CompatibleOldVersionUtil.sendRsaPublicKeyToServer(publicKey);
                                                        }
                                                    }

                                                    @Override
                                                    public void onFail(String error) {
                                                        //发送到臧老师服务器
                                                        CompatibleOldVersionUtil.sendRsaPublicKeyToServer(publicKey);
                                                    }
                                                });

//                                        //发送到臧老师服务器
//                                        CompatibleOldVersionUtil.sendRsaPublicKeyToServer(publicKey);
                                        ((Activity) mContext).runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                listener.onSuccess(publicKey);
                                            }
                                        });

                                    }
                                });

                            } else {
//                                listener.onFail("操作失败");
                                createAndUploadIMKey(userId, listener);
                            }

                        }
                    }

                    @Override
                    public void onFail(String error) {
                        listener.onFail(ResStringUtil.getString(R.string.open_planet_asset_operation_failed));
                    }
                });
    }

    /**
     * 创建并上传通讯私钥
     *
     * @param userId
     * @param listener
     */
    private void createAndUploadIMKey(final String userId, final AccountManagerListener listener) {
        //1.创建新的通讯密钥
        String[] s = RSAUtil.genKeyPair();
        final String rsaPrivateKey = s[0];
        final String rsaPublicKey = s[1];

        Disposable disposable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                //2.使用主钱包私钥加密通讯私钥
                // String messagePrivateKey = getSecretMessagePrivateKey(rsaPrivateKey);
                String messagePrivateKey = encryptByMainPrivKey(rsaPrivateKey);
                if (messagePrivateKey == null) {
                    throw new Exception("加密通讯私钥失败");
                }
                emitter.onNext(messagePrivateKey);
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String messagePrivateKey) throws Exception {
                        //3.发送到服务器
                        sendMessageKeyToServer(userId, rsaPublicKey, messagePrivateKey, rsaPrivateKey, listener);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        if (listener != null) {
                            listener.onFail(ResStringUtil.getString(R.string.open_planet_asset_operation_failed));
                        }
                    }
                });
    }

    /**
     * 发送通讯密钥到服务器
     *
     * @param userId            用户id
     * @param rsaPublicKey      通讯公钥
     * @param messagePrivateKey 加密过的通讯私钥
     * @param rsaPrivateKey     未加密的通讯私钥（本地存储）
     * @param listener
     */
    private void sendMessageKeyToServer(String userId, final String rsaPublicKey,
                                        String messagePrivateKey, final String rsaPrivateKey,
                                        final AccountManagerListener listener) {
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("userId", userId);
        hashMap.put("publicKey", rsaPublicKey);
        hashMap.put("privateKey", messagePrivateKey);
        //发送到 token服务器
        TCRequestUtil.getCommonRequest(TAG, "account/maintenanceUserSecretKey",
                hashMap, new TCRequestUtil.TCRequestCallback() {
                    @Override
                    public void onSuccess(String response) {
                        JSONObject jsonObject = JSONObject.fromObject(response);
                        if (jsonObject.optString("result", "").equals("success")) {
                            //存储到本地
                            EnvironmentVariable.setProperty(RSAUtil.getCurrentPrivateKey(), rsaPrivateKey);
                            EnvironmentVariable.setProperty(RSAUtil.getCurrentPublicKey(), rsaPublicKey);
                            listener.onSuccess(rsaPublicKey);
                        }
                    }

                    @Override
                    public void onFail(String error) {
                        listener.onFail(ResStringUtil.getString(R.string.common_text_http_server_failed));
                    }
                });
        //发送到臧老师服务器
        CompatibleOldVersionUtil.sendRsaPublicKeyToServer(rsaPublicKey);
    }

    /**
     * 上传hd的btc钱包
     * @param xpub xpub
     */
    public void addChildHdBtcWallet(final String publickey, final String privateKey,
                                    final String accountAddress, final String accountIcon,
                                    final String accountName, final String blockChainName,
                                    final String seedPhrase, final String xpub,
                                    final AccountManagerListener listener) {
        addChildWallet1(publickey, privateKey, accountAddress, accountIcon,
                accountName, blockChainName, "1", seedPhrase, xpub, listener);
    }


    //非观察钱包
    public void addChildWallet(final String publickey, final String privateKey,
                               final String accountAddress, final String accountIcon,
                               final String accountName, final String blockChainName,
                               final String seedPhrase,
                               final AccountManagerListener listener) {
        addChildWallet1(publickey, privateKey, accountAddress, accountIcon,
                accountName, blockChainName, "1", seedPhrase, "", listener);
    }

    /**
     * 新增一个钱包
     *
     * @param publickey      钱包公钥(10进制的 存后台 转成16进制额)
     * @param privateKey     钱包私钥（10进制的）
     * @param accountAddress 钱包地址
     * @param accountIcon    钱包头像
     * @param accountName    钱包名称
     * @param blockChainName 块名称
     * @param accountType 注意！这里跟Account对象中的 accounttype不完全一致！！
     *                 accountType  1、子钱包（默认值=1 ） 2、观察者钱包    3冷钱包 4 多重签名钱包
     * @param seedPhrase     助记词 空格分割的字符串
     * @param xpub hd 的 btc专用,其他可以传空
     * @param listener
     */
    public void addChildWallet1(final String publickey, final String privateKey,
                                final String accountAddress, final String accountIcon,
                                final String accountName, final String blockChainName,
                                final String accountType,
                                final String seedPhrase, final String xpub,
                                final AccountManagerListener listener) {
        //查询主账户
        final Account mainAccount = new AccountDao(mContext).getMainAccountInDb();
        if (mainAccount == null) {
            if (listener != null) {
                listener.onFail(ResStringUtil.getString(R.string.open_planet_asset_operation_failed));
            }
            return;
        }
        CommonThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
//                if (ethMainAccountPrivateKey == null) {
//                    ethMainAccountPrivateKey = PrivateKeyUtils.exportPrivateKey(mainAccount.getFileName(), "");
//                }
//                String mainPrivateKey = ethMainAccountPrivateKey;
//                //将私钥转为0X 开头 并且小写
//                if (!"0x".equals(mainPrivateKey.substring(0, 2).toLowerCase())) {
//                    mainPrivateKey = ("0x" + mainPrivateKey).toLowerCase();
//                } else {
//                    mainPrivateKey = mainPrivateKey.toLowerCase();
//                }
                //非冷钱包，使用主账户私钥 加密子账户私钥
                String secretPrivateKey = "";
                if (!"3".equals(accountType)) {
                    secretPrivateKey = encryptByMainPrivKey(convertTo16Radix(privateKey));
                }

//                if (!"".equals(privateKey)) {
//                    AESSecretUtil aesSecretUtil = new AESSecretUtil(mainPrivateKey);
//                    //以太坊
//                    secretPrivateKey = aesSecretUtil.encrypt(convertTo16Radix(privateKey));
//                }

                HashMap<String, String> hashMap = new HashMap<>();
                hashMap.put("userId", EnvironmentVariable.getProperty(CHAT_USER_ID));
                hashMap.put("accountAddress", accountAddress);
                hashMap.put("accountPublicKey", convertTo16Radix(publickey));
                //hashMap.put("accountPublicKey", publickey);
                hashMap.put("accountPrivateKey", secretPrivateKey);
                hashMap.put("mainAccountAddress", mainAccount.getAddress());
                hashMap.put("accountIcon", accountIcon);
                hashMap.put("accountName", accountName);
                hashMap.put("blockChainName", blockChainName);
                hashMap.put("accountType", accountType);

                if (blockChainName.equals(IPAssetsConstant.ChainEnum.BTC.chainName)) {
                    hashMap.put("seedPhrase", seedPhrase);
                    //主要针对Btc,如果是hd支持，那么传这个参数，与之前版本兼容
                    if (EnvSupportManager.isSupportHDWallet()) {
                        hashMap.put("isHdWallet", "1");
                        hashMap.put("xpub", xpub);
                    }
                }
                TCRequestUtil.getCommonRequest(TAG, "account/addWallet", hashMap,
                        new TCRequestUtil.TCRequestCallback() {
                            @Override
                            public void onSuccess(String response) {
                                JSONObject jsonObject = JSONObject.fromObject(response);
                                if (jsonObject.optString("result", "").equals("success")) {
                                    if (listener != null) {
                                        listener.onSuccess(ResStringUtil.getString(R.string.open_planet_asset_operation_success));
                                    }
                                } else {
                                    listener.onFail(ResStringUtil.getString(R.string.open_planet_asset_operation_failed));
                                }
                            }

                            @Override
                            public void onFail(String error) {
                                listener.onFail(ResStringUtil.getString(R.string.common_text_network_error));
                            }
                        });

            }
        });


    }

    /**
     * 转换冷热钱包
     */
    public void convertWallet(String mainAccountAddress, String address, int chainId, String privateKey,
                              String accountType, final AccountManagerListener listener) {

        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("accountAddress", address);
        hashMap.put("mainAccountAddress", mainAccountAddress);
        hashMap.put("accountType", accountType);
        if ("3".equals(accountType)) {
            hashMap.put("accountPrivateKey", "");
            hashMap.put("seedPhrase", "");
        } else {
            if (chainId == IPAssetsConstant.CHAIN_ID_ETH) {
                hashMap.put("accountPrivateKey", privateKey);
            } else if (chainId == IPAssetsConstant.CHAIN_ID_BTC) {
                hashMap.put("seedPhrase", privateKey);
            }
        }

        TCRequestUtil.getCommonRequest(TAG, "account/updateChildrenWallet", hashMap,
                new TCRequestUtil.TCRequestCallback() {
                    @Override
                    public void onSuccess(String response) {
                        try {
                            JSONObject jsonObject = JSONObject.fromObject(response);
                            if (jsonObject.optString("result", "").equals("success")) {
                                if (listener != null) {
                                    listener.onSuccess(ResStringUtil.getString(R.string.open_planet_asset_operation_success));
                                }
                            } else {
                                listener.onFail(ResStringUtil.getString(R.string.open_planet_asset_operation_failed));
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            listener.onFail(ResStringUtil.getString(R.string.common_text_network_error));
                        }
                    }

                    @Override
                    public void onFail(String error) {
                        listener.onFail(ResStringUtil.getString(R.string.common_text_network_error));
                    }
                });
    }

    /**
     * 创建EOS钱包，存后台
     *
     * @param eosAccount
     * @param mainAccount
     * @param listener
     */
    public void addEosWallet(Account eosAccount, Account mainAccount, final AccountManagerListener listener) {
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("userId", EnvironmentVariable.getProperty(CHAT_USER_ID));
        hashMap.put("accountAddress", eosAccount.getAddress());
        hashMap.put("accountPublicKey", eosAccount.getPublicKey());
        //hashMap.put("accountPublicKey", publickey);
        hashMap.put("accountPrivateKey", eosAccount.getSecretPrivateKey());
        hashMap.put("mainAccountAddress", mainAccount.getAddress());
        hashMap.put("accountIcon", eosAccount.getAccountAvatar());
        hashMap.put("accountName", eosAccount.getAcccountName());
        hashMap.put("blockChainName", EosNetParamUtil.getEosChainName());
        hashMap.put("accountType", "1");
        hashMap.put("eosAccountNames", eosAccount.getEosAccountNames());
        hashMap.put("eosActivePublicKey", eosAccount.getEosActivePubKey());
        hashMap.put("eosActivePrivateKey", eosAccount.getEosActivePriKey());
        hashMap.put("eosIsActive", eosAccount.isActivate() ? "1" : "0");
        TCRequestUtil.getCommonRequest(TAG, "account/addWallet", hashMap,
                new TCRequestUtil.TCRequestCallback() {
                    @Override
                    public void onSuccess(String response) {
                        JSONObject jsonObject = JSONObject.fromObject(response);
                        if (jsonObject.optString("result", "").equals("success")) {
                            if (listener != null) {
                                listener.onSuccess(ResStringUtil.getString(R.string.open_planet_asset_operation_success));
                            }
                        } else {
                            listener.onFail(ResStringUtil.getString(R.string.open_planet_asset_operation_failed));
                        }
                    }

                    @Override
                    public void onFail(String error) {
                        listener.onFail(ResStringUtil.getString(R.string.common_text_network_error));
                    }
                });
    }

    /**
     * 使用主账户的私钥加密通讯私钥
     *
     * @param rsaPrivateKey 通讯私钥
     * @return
     */
//    public String getSecretMessagePrivateKey(String rsaPrivateKey) {
//        String secretMessagePrivateKey = encryptByMainPrivKey(rsaPrivateKey);
//        return secretMessagePrivateKey;
//    }

    /**
     * 通过主账户的助记词，生成多个账户钱包
     *
     * @param number   手机号，用于存储wallet文件
     * @param mnemonic 助记词
     */
    public Observable<String> createChildWalletByMnemonic(final String number, final String mnemonic) {
        return Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                //用助记词创建btc账户
                String btcPath = TalkChainConstant.getChildAccountFilePath(mContext) +
                        File.separator + number;
                Account btcAccount = BTCAccountGenerator.recoverBtcAccountSync(btcPath, mnemonic,
                        "BTC-Wallet", "");

                //创建未激活的eos账户
                EosAccountGenerator eosAccountGenerator = new EosAccountGenerator(mContext);
                Account eosAccount = eosAccountGenerator.generateEosKeysAndAccount("EOS-Wallet", "");

                String childKeystorePath = TalkChainConstant.getChildAccountFilePath(mContext) + File.separator + EnvironmentVariable.getUserName();
                File childDir = new File(childKeystorePath);
                if (!childDir.exists()) {
                    childDir.mkdirs();
                }

//                EthHdWallet eteHdWallet = (EthHdWallet) new HDAccountManager().createEteWallet(HDWalletUtil.mnemonicString2List(mnemonic),
//                        "", childKeystorePath);

                EthHdWallet eteHdWallet = (EthHdWallet) new HDAccountManager().createWallet(HDWalletUtil.mnemonicString2List(mnemonic),
                        "", childKeystorePath, IPAssetsConstant.ChainEnum.ETE);

                Account eteAccount = new Account();
                eteAccount.setAddress(eteHdWallet.getAddress());
                eteAccount.setSecretPrivateKey(TCAccountManager.encryptByMainPrivKey(eteHdWallet.getPrivateKey()));
                eteAccount.setPublicKey(eteHdWallet.getPublicKey());
                eteAccount.setFileName(eteHdWallet.getFilePath());
                eteAccount.setImUserId(EnvironmentVariable.getProperty(CHAT_USER_ID));
                eteAccount.setMainAccoutAddress(EnvironmentVariable.getProperty("tc_ethAddress", ""));
                eteAccount.setBlockChainName(IPAssetsConstant.ChainEnum.ETE.chainName);
                eteAccount.setCreateTime(TimeUtils.getNowString());
                eteAccount.setEnable(false);
                //创建bch账户
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    //                Account bchAccount = BchAccountGenerator.recoverBchAccountSync(btcPath, mnemonic,
//                        "BCH-Wallet", "");

                //创建act账户

                //调接口上传服务器
                List<Account> accounts = new ArrayList<>();
                accounts.add(btcAccount);
                accounts.add(eosAccount);
                String success = addChildToServer(mContext, accounts);
                AccountDao accountDao = new AccountDao(mContext);
                //成功则更改本地数据库
                if (success.equals("success")) {
                    eosAccount.setEnable(true);
                    accountDao.insertOrReplace(eosAccount);
                    btcAccount.setEnable(true);
                    accountDao.insertOrReplace(btcAccount);
                    eteAccount.setEnable(true);
                    accountDao.insertOrReplace(eteAccount);
//                    bchAccount.setEnable(true);
//                    accountDao.insertOrReplace(bchAccount);
                }
                emitter.onNext(success);
                emitter.onComplete();
            }
        });
    }

    /**
     * 将生成的子钱包账户转成json
     *
     * @param account
     * @return
     */
    private org.json.JSONObject accountToJSON(Account account) {

        HashMap<String, String> map = new HashMap<>();
        map.put("accountAddress", account.getAddress());
        map.put("accountPublicKey", account.getPublicKey());
        map.put("accountPrivateKey", account.getSecretPrivateKey());
        map.put("mainAccountAddress", account.getMainAccoutAddress());
        map.put("accountIcon", "");
        map.put("accountName", account.getAcccountName());
        map.put("blockChainName", account.getBlockChainName());
        //历史原因，服务器type比本地多1
        map.put("accountType", (account.getAccountType() + 1) + "");
        map.put("seedPhrase", account.getSecretMnemonic());
        map.put("eosActivePublicKey", account.getEosActivePubKey());
        map.put("eosActivePrivateKey", account.getEosActivePriKey());
        map.put("eosAccountNames", account.getEosAccountNames());
        map.put("eosIsActive", String.valueOf(account.isActivate()));
        //主要针对Btc,如果是hd支持，那么传这个参数，与之前版本兼容
        if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.BTC.chainName)) {
            if (EnvSupportManager.isSupportHDWallet()) {
                map.put("isHdWallet", "1");
                map.put("xpub", account.getHdBtcXpub());
            }
        }
        return new org.json.JSONObject(map);
    }

    /**
     * 添加多个子钱包到服务器
     */
    public String addChildToServer(Context context, List<Account> accounts) {

        try {
            org.json.JSONArray jsonArray = new org.json.JSONArray();
            for (int i = 0; i < accounts.size(); i++) {
                jsonArray.put(accountToJSON(accounts.get(i)));
            }

            JFCommonRequestManager manager = JFCommonRequestManager.getInstance(context);
            Response response = manager.requestPostByJSONSyn(TAG, BASE_URL +
                    "/account/addWalletList", jsonArray.toString());
            String responseString = response.body().string();
            LogUtils.d(responseString);
            org.json.JSONObject object = new org.json.JSONObject(responseString);
            if (object.optString("result").equals("success")) {
                return "success";
            } else {
                return "fail";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }

    /**
     * 将添加的卡片上传到服务器
     *
     * @param uid                卡号
     * @param mainAccountAddress 用户主钱包地址
     * @return 结果
     */
    public boolean addCardToServer(String uid, String mainAccountAddress) {
        try {
            HashMap<String, String> map = new HashMap<>();
            map.put("id", uid);
            map.put("mainAccountAddress", mainAccountAddress);
            JFCommonRequestManager manager = JFCommonRequestManager.getInstance(mContext);
            Response response = manager.requestGetBySyn(TAG, BASE_URL + "/card/addCard", map);
            String result = response.body().string();
            org.json.JSONObject jsonObject = new org.json.JSONObject(result);
            return "success".equals(jsonObject.optString("result"));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将冷钱包上传到服务器
     *
     * @param uid                卡片卡号
     * @param cardInfo           钱包信息
     * @param mainAccountAddress 主账户地址
     * @return 结果
     */
    public boolean addCardWalletToServer(String uid, String cardInfo, String mainAccountAddress,
                                         String address, String icon, String name, String chainId,
                                         String position) {
        try {
            HashMap<String, String> map = new HashMap<>();
            map.put("accountAddress", address);
            map.put("mainAccountAddress", mainAccountAddress);
            map.put("accountIcon", icon);
            map.put("accountName", name);
            map.put("blockchainId", chainId);
            //历史原因，服务器type比本地多1
            map.put("accountType", "3");
            map.put("cardId", uid);
            map.put("index", position);
            map.put("cardInfo", cardInfo);
            if (chainId.equals(IPAssetsConstant.CHAIN_ID_BTC + "")) {
                //主要针对Btc,如果是hd支持，那么传这个参数，与之前版本兼容
                if (EnvSupportManager.isSupportHDWallet()) {
                    map.put("isHdWallet", "1");
                }
            }
            JFCommonRequestManager manager = JFCommonRequestManager.getInstance(mContext);
            Response response = manager.requestGetBySyn(TAG, BASE_URL + "/card/addCardColdWallet", map);
            String result = response.body().string();
            org.json.JSONObject jsonObject = new org.json.JSONObject(result);
            return "success".equals(jsonObject.optString("result"));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 根据钱包地址及卡号，删除这个钱包，同时资产里的这个钱包也会同步被删除
     *
     * @param
     * @return
     */
    public boolean deleteCardWallet(String address, String cardNo, String cardInfo) {
        try {
            HashMap<String, String> map = new HashMap<>();
            map.put("accountAddress", address);
            map.put("cardId", cardNo);
            map.put("cardInfo", cardInfo);
            JFCommonRequestManager manager = JFCommonRequestManager.getInstance(mContext);
            Response response = manager.requestGetBySyn(TAG, BASE_URL + "/card/deleteCardColdWallet", map);
            String result = response.body().string();
            org.json.JSONObject jsonObject = new org.json.JSONObject(result);
            return "success".equals(jsonObject.optString("result"));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据钱包地址及卡号，删除这个钱包，同时资产里的这个钱包也会同步被删除
     *
     * @param
     * @return
     */
    public boolean removeCard(String address, String cardNo) {
        try {
            HashMap<String, String> map = new HashMap<>();
            map.put("mainAccountAddress", address);
            map.put("id", cardNo);
            JFCommonRequestManager manager = JFCommonRequestManager.getInstance(mContext);
            Response response = manager.requestGetBySyn(TAG, BASE_URL + "/card/deleteCardByMainAccountAddress", map);
            String result = response.body().string();
            org.json.JSONObject jsonObject = new org.json.JSONObject(result);
            return "success".equals(jsonObject.optString("result"));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 钱包冷热转换
     *
     * @param mainAccountAddress 主钱包地址
     * @param cardId             卡片编号
     * @param chainId            钱包的链编号
     * @param accountType        账户类型 1 热钱包 3冷钱包
     * @param accountAddress     钱包地址
     * @param index              冷钱包在卡片的位置
     * @param cardInfo           卡片的卡片信息
     * @param seedPhrase         btc加密的助记词
     * @param accountPrivateKey  eth加密的私钥
     * @return 结果
     */
    public boolean convertCardWallet(String mainAccountAddress, String cardId, String chainId, String accountType,
                                     String accountAddress, String index, String cardInfo, String seedPhrase,
                                     String accountPrivateKey) {
        try {
            HashMap<String, String> map = new HashMap<>();
            map.put("mainAccountAddress", mainAccountAddress);
            map.put("cardId", cardId);
            map.put("blockchainId", chainId);
            map.put("accountType", accountType);
            map.put("accountAddress", accountAddress);
            map.put("index", index);
            map.put("cardInfo", cardInfo);
            map.put("seedPhrase", seedPhrase);
            map.put("accountPrivateKey", accountPrivateKey);
            if (chainId.equals(IPAssetsConstant.CHAIN_ID_BTC + "")) {
                //主要针对Btc,如果是hd支持，那么传这个参数，与之前版本兼容
                if (EnvSupportManager.isSupportHDWallet()) {
                    map.put("isHdWallet", "1");
                }
            }
            JFCommonRequestManager manager = JFCommonRequestManager.getInstance(mContext);
            Response response = manager.requestGetBySyn(TAG, BASE_URL + "/card/walletColdAndHeatTransfer", map);
            String result = response.body().string();
            org.json.JSONObject jsonObject = new org.json.JSONObject(result);
            return "success".equals(jsonObject.optString("result"));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 恢复子钱包
     *
     * @param mainAddress
     * @param listener
     */
    public void restoreChildWallet(final String mainAddress, final AccountManagerListener listener) {
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("mainAccountAddress", mainAddress);
//        listener.onFail("");
//        if (true){
//            return;
//        }

        TCRequestUtil.getCommonRequest(TAG, "account/getAllWallet",
                hashMap, new TCRequestUtil.TCRequestCallback() {
                    @Override
                    public void onSuccess(String response) {
//                        {
//                            "result": "success",
//                                "ChildrenWallet": [
//                            {
//                                "accountAddress": "0xa3e64f5dea0613b6e907a38964f4d25a86fa45b5",
//                                    "accountIcon": "",
//                                    "accountName": "",
//                                    "accountPrivateKey": "x03MlEc5SbTZJ3itoVs26uaARxqvhoJyDjFohRqAoITCyzztSDH3q8SoNKOCs3EMzMs9ycXdGoPr\ndRO5eZkjiVNAz1prhz4WQgT70lOdEGg=",
//                                    "accountPublicKey": "4739579412879023572756153125418544423000866872851014281031151150448271258542814904959310583382203545828416304740686980530814748570304386478973424737023061",
//                                    "blockChainName": "ETH",
//                                    "id": "271871b0-38cb-45c3-8346-5d0e96f7d9b2",
//                                    "mainAccountAddress": "0xf88bad42d68d3440151061d23eb4a61d6e7fa694"
//                            }
//    ]
//                        }
                        try {
                            JSONObject jsonObject = JSONObject.fromObject(response);
                            if (jsonObject.optString("result", "").equals("success")) {
                                if (jsonObject.containsKey("ChildrenWallet") && jsonObject.get("ChildrenWallet") != null) {
                                    JSONArray jsonArray = jsonObject.getJSONArray("ChildrenWallet");
                                    List<Account> accounts = new ArrayList<>();
                                    for (int i = 0; i < jsonArray.size(); i++) {
                                        Account account = new Account();
                                        account.setMainAccoutAddress(mainAddress);
                                        account.setCurrentShow(false);
                                        account.setMaster(false);


                                        String blockChainName = jsonArray.getJSONObject(i).optString("blockChainName", "");

                                        //todo 数据库中 eth的公钥存的十进制    btc 的存的 16进制
                                        String publicKey = jsonArray.getJSONObject(i).optString("accountPublicKey", "");
                                        if (blockChainName.equals(IPAssetsConstant.ChainEnum.ETH.chainName)) {
                                            account.setPublicKey(convertTo10Radix(publicKey));
                                        } else {
                                            account.setPublicKey(publicKey);
                                        }

                                        if (blockChainName.equals(EosNetParamUtil.getEosChainName())) {
                                            account.setEosActivePriKey(jsonArray.getJSONObject(i).optString("eosActivePrivateKey", ""));
                                            account.setEosActivePubKey(jsonArray.getJSONObject(i).optString("eosActivePublicKey", ""));
                                            account.setActivate(jsonArray.getJSONObject(i).optInt("eosIsActive", 0) == 1);
                                            account.setEosAccountNames(jsonArray.getJSONObject(i).optString("eosAccountNames", ""));
                                        }

                                        String accountType = jsonArray.getJSONObject(i).optString("accountType", "1");

                                        account.setSecretPrivateKey(jsonArray.getJSONObject(i).optString("accountPrivateKey"));
                                        account.setAccountAvatar(jsonArray.getJSONObject(i).optString("accountIcon", ""));
                                        account.setAcccountName(jsonArray.getJSONObject(i).optString("accountName", ""));
                                        account.setBlockChainName(blockChainName);
                                        account.setAddress(jsonArray.getJSONObject(i).optString("accountAddress", ""));
                                        account.setSecretMnemonic(jsonArray.getJSONObject(i).optString("seedPhrase", ""));
                                        //是否是hd钱包，主要用于btc钱包恢复兼容之前
                                        account.setHdWallet("1".equals(jsonArray.getJSONObject(i).optString("isHdWallet", "0")));
                                        //服务器1,2,3分别对应子钱包，观察钱包，冷钱包
                                        //数据库里0,1,2分别对应子钱包，观察钱包，冷钱包
                                        if ("1".equals(accountType)) {
                                            //子钱包
                                            account.setAccountType(Account.ACCOUNT_TYPE_COMMON);
                                        } else if ("2".equals(accountType)) {
                                            //观察钱包
                                            account.setAccountType(Account.ACCOUNT_TYPE_OBSERVE);
                                        } else if ("3".equals(accountType)) {
                                            //冷钱包
                                            account.setAccountType(Account.ACCOUNT_TYPE_COLD);
                                        } else {
                                            account.setAccountType(Account.ACCOUNT_TYPE_COMMON);
                                        }

                                        if (!mainAddress.toLowerCase()
                                                .equals(jsonArray.getJSONObject(i).optString("accountAddress", "").toLowerCase())) {
                                            accounts.add(account);
                                        }
                                    }
                                    restoreByRXjava(accounts, listener);
                                } else {
                                    listener.onSuccess(ResStringUtil.getString(R.string.open_planet_asset_restoring_child_success));
                                }


                            } else {
                                if (jsonObject.optString("msg", "").equals("没有获取到此主钱包地址的钱包信息，请检查输入mainAccountAddress是否正确！")) {
                                    listener.onSuccess(ResStringUtil.getString(R.string.open_planet_asset_restoring_child_success));
                                    return;
                                }

                                if (listener != null) {
                                    listener.onFail(ResStringUtil.getString(R.string.open_planet_asset_restore_child_wallet_fails));
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            if (listener != null) {
                                listener.onFail(ResStringUtil.getString(R.string.open_planet_asset_restore_child_wallet_fails));
                            }
                        }
                    }

                    @Override
                    public void onFail(String error) {
                        if (listener != null) {
                            listener.onFail(ResStringUtil.getString(R.string.open_planet_asset_restore_child_wallet_fails));
                        }
                    }
                });

    }

    //rxJava恢复
    public void restoreByRXjava(final List<Account> accounts, final AccountManagerListener listener) {
        disposable = Observable.create(new ObservableOnSubscribe<List<EthBean>>() {
            @Override
            public void subscribe(ObservableEmitter<List<EthBean>> emitter) throws Exception {
                List<EthBean> list = new ArrayList<>();
//                Account mainAccount = new AccountDao(mContext).getMainAccountInDb();
//                if (mainAccount == null) {
//                    throw new RuntimeException("主账户为空");
//                }
//                if (ethMainAccountPrivateKey == null) {
//                    ethMainAccountPrivateKey = PrivateKeyUtils.exportPrivateKey(mainAccount.getFileName(), "");
//                }
                //String mainPrivateKey = ethMainAccountPrivateKey;
                String mainPrivateKey = getMainPrivateKey();
                //将私钥转为0X 开头 并且小写
                if (!"0x".equals(mainPrivateKey.substring(0, 2).toLowerCase())) {
                    mainPrivateKey = ("0x" + mainPrivateKey).toLowerCase();
                } else {
                    mainPrivateKey = mainPrivateKey.toLowerCase();
                }
                //todo 有的主账户以 0c 开头  android 会省略掉0
                String tempPrivateKey = "";
                AESSecretUtil tempAesUtil = null;
                if (mainPrivateKey != null && mainPrivateKey.startsWith("0xc")) {
                    tempPrivateKey = mainPrivateKey.replace("0xc", "0x0c");
                    tempAesUtil = new AESSecretUtil(tempPrivateKey);
                }

                //子账户文件目录
                String childKeystorePath = TalkChainConstant.getChildAccountFilePath(mContext) + File.separator + EnvironmentVariable.getUserName();
                File childDir = new File(childKeystorePath);
                if (!childDir.exists()) {
                    childDir.mkdirs();
                }
                for (int i = 0; i < accounts.size(); i++) {
                    Account curentAccount = accounts.get(i);
                    if (curentAccount.getAccountType() == Account.ACCOUNT_TYPE_OBSERVE || curentAccount.getAccountType() == Account.ACCOUNT_TYPE_COLD) {
                        //观察者钱包不需要恢复，直接等待存入数据库即可
                        //冷钱包也直接存数据库
                        curentAccount.setEnable(true);
                        continue;
                    }
                    //解密 子账户钱包的私钥
                    String currentPrivateKey = null;
                    AESSecretUtil aesSecretUtil = new AESSecretUtil(mainPrivateKey);
                    try {
                        currentPrivateKey = aesSecretUtil.decrypt(curentAccount.getSecretPrivateKey());
                    } catch (Exception e) {
                        e.printStackTrace();

                        try {
                            if (tempAesUtil != null && !tempPrivateKey.equals("")) {
                                aesSecretUtil = tempAesUtil;
                                currentPrivateKey = tempAesUtil.decrypt(curentAccount.getSecretPrivateKey());
                            }
                        } catch (Exception e1) {
                            e1.printStackTrace();
                        }
                    }


                    if (currentPrivateKey == null || "".equals(currentPrivateKey)) {
                        continue;
                    }
                    if (curentAccount.getBlockChainName().equals(IPAssetsConstant.ChainEnum.BTC.chainName)) {
                        //btc
                        String secretWord = curentAccount.getSecretMnemonic();
                        if (secretWord == null || "".equals(secretWord)) {
                            continue;
                        }
                        String word = aesSecretUtil.decrypt(secretWord);
//                        LogUtils.i("解密助记词：", secretWord, word);
                        recoverBtcWallet(childKeystorePath, curentAccount, word);
                    } else if (curentAccount.getBlockChainName().equals(EosNetParamUtil.getEosChainName())) {
                        //eos
                        String ownerPriKey = aesSecretUtil.decrypt(curentAccount.getSecretPrivateKey());
                        String activePriKey = aesSecretUtil.decrypt(curentAccount.getEosActivePriKey());
                        recoverEOSWallet(ownerPriKey, activePriKey, curentAccount);
                    } else if (curentAccount.getBlockChainName().equals(IPAssetsConstant.ChainEnum.ETH.chainName)) {
                        //eth
                        EthBean ethBean = recoverEthWallet(childKeystorePath, curentAccount, currentPrivateKey);
                        list.add(ethBean);
                    } else if (curentAccount.getBlockChainName().equals(IPAssetsConstant.ChainEnum.ACHAIN.chainName)) {
                        //act
                        recoverActWallet(curentAccount, currentPrivateKey);

                    } else if (curentAccount.getBlockChainName().equals(IPAssetsConstant.ChainEnum.BCH.chainName)) {
                        //bch
                        String secretWord = curentAccount.getSecretMnemonic();
                        if (secretWord == null || "".equals(secretWord)) {
                            continue;
                        }
                        String word = aesSecretUtil.decrypt(secretWord);
//                        LogUtils.i("解密BCH助记词：", secretWord, word);
                        // FIXME: 19-11-1 BCH库跟更新的bitcoinj有冲突，暂时屏蔽
//                        recoverBchWallet(childKeystorePath, curentAccount, word);
                    } else if (curentAccount.getBlockChainName().equals(IPAssetsConstant.ChainEnum.ETE.chainName)) {
                        EthBean ethBean = recoverEthWallet(childKeystorePath, curentAccount, currentPrivateKey);
                        list.add(ethBean);
                    }
                }
                emitter.onNext(list);

            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<List<EthBean>>() {
            @Override
            public void accept(List<EthBean> ethBeans) throws Exception {
                if (accounts != null) {
                    for (int i = 0; i < accounts.size(); i++) {
                        if (accounts.get(i).isEnable()) {
                            new AccountDao(mContext).insertOrReplace(accounts.get(i));
                        }
                    }
                }
                listener.onSuccess(ResStringUtil.getString(R.string.open_planet_recovering_success));
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                listener.onFail(ResStringUtil.getString(R.string.open_planet_recovering_fail));
            }
        });
    }


    /**
     * 恢复 act钱包
     *
     * @param curentAccount
     * @param currentPrivateKey
     */
    private void recoverActWallet(Account curentAccount, String currentPrivateKey) {
//        ActGeneratorBean bean = ActAccountGenerator.recoverByPrivateKeySync(currentPrivateKey);
        //todo 恢复act 无需进行任何操作
        curentAccount.setEnable(true);
    }


    /**
     * 恢复btc 钱包
     *
     * @param childKeystorePath
     * @param curentAccount
     * @param word              助记词（解密之后的）
     */
    private void recoverBtcWallet(String childKeystorePath, Account curentAccount, String word) throws Exception {
        BtcBean btcBean;
        if (EnvSupportManager.isSupportHDWallet() && curentAccount.isHdWallet()) {
            //恢复所有子钱包，如果现在支持hd，但是服务器上的钱包不是hd的，那么还用之前的方法恢复
            btcBean = BTCAccountGenerator.createBtcBeanFromHdWallet(word);
            curentAccount.setHdBtcXpub(btcBean.getHdBtcXpub());
            curentAccount.setHdBtcMaxChildIndex(btcBean.getHdBtcMaxChildIndex());
            curentAccount.setHdBtcCurrentChildAddress(btcBean.getHdBtcCurrentChildAddress());
        } else {
            //助记词恢复
            btcBean = BTCMnemonicUtils.restoreByMnemonic(word, "");
            //文件名
            SimpleDateFormat dateFormat = new SimpleDateFormat("'BTC--'yyyy-MM-dd'T'HH-mm-ss.SSS'--'");
            String fileName = dateFormat.format(new Date()) + btcBean.getBtcAddress() + ".wallet";
            File keyStoreFile = new File(childKeystorePath, fileName);
            btcBean.getWallet().saveToFile(keyStoreFile);
            btcBean.setKeyStoreFilePath(keyStoreFile.getAbsolutePath());
            curentAccount.setFileName(keyStoreFile.getAbsolutePath());
        }
        //放到account中
        curentAccount.setEnable(true);
    }

    /**
     * 恢复bch 钱包
     *
     * @param childKeystorePath
     * @param curentAccount
     * @param word              助记词（解密之后的）
     */
    private void recoverBchWallet(String childKeystorePath, Account curentAccount, String word) throws Exception {
        //助记词恢复
        BchGeneratorBean bchBean = BchMnemonicUtils.restoreByMnemonic(word, "");
        //文件名
        SimpleDateFormat dateFormat = new SimpleDateFormat("'BCH--'yyyy-MM-dd'T'HH-mm-ss.SSS'--'");
        String fileName = dateFormat.format(new Date()) + bchBean.getWalletAddress() + ".wallet";
        File keyStoreFile = new File(childKeystorePath, fileName);
        bchBean.getWallet().saveToFile(keyStoreFile);
        bchBean.setKeyStoreFilePath(keyStoreFile.getAbsolutePath());
        //放到account中
        curentAccount.setEnable(true);
        curentAccount.setFileName(keyStoreFile.getAbsolutePath());

    }

    @NonNull
    /**
     * 恢复eth子钱包
     */
    private EthBean recoverEthWallet(String childKeystorePath, Account curentAccount, String currentPrivateKey)
            throws Exception {
        BigInteger privateKey = null;
        if (!isNumer(currentPrivateKey)) {
            if ("0x".equals(currentPrivateKey.substring(0, 2).toLowerCase())) {
                //去掉0X
                currentPrivateKey = currentPrivateKey.substring(2, currentPrivateKey.length());
                privateKey = new BigInteger(currentPrivateKey, 16);
            } else {
                privateKey = new BigInteger(currentPrivateKey, 16);
            }
        } else {
            privateKey = new BigInteger(currentPrivateKey);
        }

        ECKeyPair ecKeyPair = ECKeyPair.create(privateKey);
        WalletFile walletFile = Wallet.createLight("", ecKeyPair);
        SimpleDateFormat dateFormat = new SimpleDateFormat("'UTC--'yyyy-MM-dd'T'HH-mm-ss.SSS'--'");
        String fileName = dateFormat.format(new Date()) + walletFile.getAddress() + ".json";
        File destination = new File(childKeystorePath, fileName);
        ObjectMapper objectMapper = new ObjectMapper();
        //写入文件
        objectMapper.writeValue(destination, walletFile);
        File realFile = new File(childKeystorePath + File.separator + fileName);
        EthBean ethBean = new EthBean.Builder().walletFile(walletFile)
                .ecKeyPair(ecKeyPair).ethAddress("0x" + walletFile.getAddress())
                .keyStoreFilePath(realFile.getAbsolutePath())
                .build();
        LogUtils.i(TAG, ethBean.getEthAddress());
        curentAccount.setEnable(true);
        curentAccount.setFileName(ethBean.getKeyStoreFilePath());
        return ethBean;
    }

    /**
     * 恢复EOS账户
     */
    private void recoverEOSWallet(String ownerPrivKey, String activePrivKey, Account curentAccount) throws Exception {
        curentAccount.setEnable(true);
    }

    /**
     * 判断是否是16进制
     *
     * @param text
     * @return
     */
    public static boolean is16Radix(String text) {
        if (text == null || "".equals(text)) {
            return false;
        }
        if ("0x".equals(text.substring(0, 2).toLowerCase())) {
            text = text.substring(2, text.length());
        }
        String regex = "^[A-Fa-f0-9]+$";
        if (text.matches(regex)) {
            return true;
        } else {
            return false;
        }

    }

    //判断是否是数字
    public static boolean isNumer(String str) {
        for (int i = 0; i < str.length(); i++) {
            System.out.println(str.charAt(i));
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 钱包10进制转16进制
     *
     * @param str
     * @return
     */
    public static String convertTo16Radix(String str) {
        if (TextUtils.isDigitsOnly(str)) {
            //如果是数字，十进制转16进制 加0x开头，不是的话，直接返回字符串
            BigInteger bigInteger = new BigInteger(str);
            String key = bigInteger.toString(16);
            if (key.length() == 63) {
                //私钥如果是63位需要补0
                key = "0" + key;
            }
            return "0x" + key;
        }
        return str;

    }

    /**
     * 钱包公钥 转换为十进制
     *
     * @param str
     * @return
     */
    public static String convertTo10Radix(String str) {
        if (str == null) {
            return null;
        }
        if ("".equals(str)) {
            return str;
        }
        //全是数字 表示已经是10进制了
        if (isNumer(str)) {
            return str;
        }
        if ("0x".equals(str.substring(0, 2).toLowerCase())) {
            str = str.substring(2, str.length());
        }
        //ios 公钥长度 130 需要去掉前两位
        if (str.length() == 130) {
            str = str.substring(2, str.length());
        }
        //16转10
        BigInteger bigInteger = new BigInteger(str, 16);
        return bigInteger.toString(10);
    }

    public interface AccountManagerListener<T> {

        void onSuccess(T object);

        void onFail(String fail);
    }


    /**
     * 使用主钱包私钥加密 字符
     *
     * @param value
     * @return
     */
    public static String encryptByMainPrivKey(String value) {
        String mainPrivateKey = getMainPrivateKey();
        //钱包私钥是63位，前面需要补0
        if (mainPrivateKey != null && mainPrivateKey.length() == 63) {
            mainPrivateKey = "0" + mainPrivateKey;
        }
        //将私钥转为0X 开头 并且小写
        if (!"0x".equals(mainPrivateKey.substring(0, 2).toLowerCase())) {
            mainPrivateKey = ("0x" + mainPrivateKey).toLowerCase();
        } else {
            mainPrivateKey = mainPrivateKey.toLowerCase();
        }
        AESSecretUtil aesSecretUtil = new AESSecretUtil(mainPrivateKey);
        String secretString = aesSecretUtil.encrypt(value);
        LogUtils.i("加密操作：", value, secretString);
        return secretString;
    }

    /**
     * 使用主钱包私钥解密字符
     *
     * @param value
     * @return
     */
    public static String decryptByMainPrivKey(String value) {

        String mainPrivateKey = getMainPrivateKey();
        //钱包私钥是63位，前面需要补0 , 有的主账户以 0c开头  android会省略掉0,变成63位，所以我们需要补0
        if (mainPrivateKey != null && mainPrivateKey.length() == 63) {
            mainPrivateKey = "0" + mainPrivateKey;
        }
        //将私钥转为0X 开头 并且小写
        if (!"0x".equals(mainPrivateKey.substring(0, 2).toLowerCase())) {
            mainPrivateKey = ("0x" + mainPrivateKey).toLowerCase();
        } else {
            mainPrivateKey = mainPrivateKey.toLowerCase();
        }
        AESSecretUtil aesSecretUtil = new AESSecretUtil(mainPrivateKey);
        String decreptString = aesSecretUtil.decrypt(value);
//        LogUtils.i("解密操作：", value, decreptString);
        return decreptString;
    }

    /**
     * 获取主钱包私钥
     * 注意：这个私钥格式可能存在问题。没有0x 正常位数应该64 有时候会出现63位的情况
     *
     * @return
     */
    public static String getMainPrivateKey() {
        Account mainAccount = new AccountDao(AppContext.getInstance()).getMainAccountInDb();
        if (mainAccount == null) {
            return null;
        }
        if (ethMainAccountPrivateKey == null) {
            ethMainAccountPrivateKey = PrivateKeyUtils.exportPrivateKey(mainAccount.getFileName(), "");
        }
        String mainPrivateKey = ethMainAccountPrivateKey;
        return mainPrivateKey;
    }

    public static void release() {
        ethMainAccountPrivateKey = null;
    }
}
